package com.example.demo.controller.game;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
// 存了所有飞机、检查点相关的信息
public class MapCtrl {
    Pot pots[];
    Vec checkPoints[];
    final double DELTA_TIME = 0.5;
    final double FRC_K = 0.2;
    final double POT_RADIAS = 500;
    final int HEIGHT = 9000;
    final int WEIGHT = 16000;

    public MapCtrl(int count,String ...usernames){
        generateCheckPoints(count);

        int userNum = usernames.length;
        pots = new Pot[userNum];
        for(int i=0;i<userNum;i++){
            pots[i] = new Pot(usernames[i]);
            pots[i].pos = checkPoints[0].add(new Vec(100,100).mul(i));
        }
    }
    public Vec[] generateCheckPoints(int count){
        Random random = new Random(System.currentTimeMillis());
        List<Vec> list = new ArrayList<>();
        for(int i=0;i<count;i++){
            list.add(new Vec(random.nextInt(WEIGHT),random.nextInt(HEIGHT)));
        }
        checkPoints = list.toArray(new Vec[0]);
        return checkPoints;
    }
    public Pot[] play(List<PlaneCmd> cmds){
        // 处理加速度、摩擦力
        for (int i = 0;i<cmds.size();i++){
            PlaneCmd cmd = cmds.get(i);
            Pot pot = pots[i];

//            System.out.println(cmd.toString());
            if(cmd.thrust.equals("BOOST")){

            }else{
                // 扭转机头，确定飞机角度


                // 推力 = （目标位置 - 飞船位置）.单位化()*油门大小
                Vec force = new Vec(cmd.x,cmd.y).sub(pot.pos).nomal().mul(Double.parseDouble(cmd.thrust));
                // 摩擦力 = 速度的反方向* km
                Vec friction;
                if(pot.speed.len() == 0){
                    friction = new Vec(0,0);
                }else{
                    friction = pot.speed.nomal().mul(-1* FRC_K *pot.mass);
                }
                // 新的速度 += （推力+摩擦力)*时间
                pot.speed = pot.speed.add(force.add(friction).mul(DELTA_TIME));
                // 新的位置 += 速度*时间
                pot.pos = pot.pos.add(pot.speed.mul(DELTA_TIME));
            }
        }
        // 处理碰撞
        for(int i=0;i<pots.length;i++){
            for(int j=i+1;j<pots.length;j++){
                Pot a = pots[i];
                Pot b = pots[j];
                solveCollision(a,b);
            }
        }

        // 处理检查点
        for(Pot pot : pots){
            for(int i=0;i<checkPoints.length;i++){
                Vec point = checkPoints[i];
                if(pot.dis(point)<=600 && pot.visited.get(pot.visited.size()-1) != i){
                    pot.visited.add(i);
                }
            }
        }
        return pots;
    }

    private void solveCollision(Pot a, Pot b){
        if(willCollision(a,b)){
            switchSpeedCollision(a,b);
        }
    }
    private boolean willCollision(Pot a,Pot b){
        if(a.dis(b) > 2*POT_RADIAS){
            return false;
        }
        // a.speed*(b.pos-a.pos) a的速度在ab连线上的分量长度
        double asl = a.speed.doc(b.pos.sub(a.pos));
        // b.speed*(a.pos-b.pos)
        double bsl = b.speed.doc(a.pos.sub(b.pos));
        return asl + bsl > 0;
    }
    private void switchSpeedCollision(Pot a,Pot b){
        // a.speed*(b.pos-a.pos) a的速度在ab连线上的分量长度
        double asl = a.speed.doc(b.pos.sub(a.pos));
        // b.speed*(a.pos-b.pos)
        double bsl = b.speed.doc(a.pos.sub(b.pos));

        // 根据长度算出a.speed在ab连线上的速度分量的矢量
        Vec as = b.pos.sub(a.pos).mul(asl);
        Vec bs = a.pos.sub(b.pos).mul(bsl);

        // 计算a.spped在ab垂直方向的速度分量
        Vec at = a.speed.sub(as);
        Vec bt = b.speed.sub(bs);

        // 新的a.speed = at+bs a的水平分量+b的垂直分量
        a.speed = at.add(bs);
        b.speed = bt.add(as);
    }
}
